using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Practices.EnterpriseLibrary.Data;

using Syncfusion.Windows.Forms.Grid;
using ctsu.BaseForms;
using ctsu.Data;
using ctsu.Admin.Forms;

namespace ctsu.Admin.BusLogic.CoreLab
{
	public class BLCoreLabFormGridSamplesCheckOut : BLCoreLabFormGridBaseImpl
	{
		private CheckBox _chkResultOnly;

		public BLCoreLabFormGridSamplesCheckOut(FormGridMeta formGridMeta, GridControl grid, FormInfoBase formInfo, Form form)
			: base(formGridMeta, grid, formInfo, form)
		{
		}

		#region initialize
		public override bool Initialize()
		{
			_errorControl = (Label)Forms.Utils.GetControlByName("errCtl", this._form.Controls);
			_btnEditBatch = (Button)Forms.Utils.GetControlByName("btnEditBatch", this._form.Controls);
			_btnRemoveBatch = (Button)Forms.Utils.GetControlByName("btnRemoveBatch", this._form.Controls);
			_btnPrint = (Button)Forms.Utils.GetControlByName("btnPrint", this._form.Controls);
			_btnSave = (Button)Forms.Utils.GetControlByName("btnSave", this._form.Controls);
			_chkResultOnly = (CheckBox)Forms.Utils.GetControlByName("chkResultOnly", this._form.Controls);

			StringBuilder sb = new StringBuilder();
			string sql = "SELECT t.ID, t.DrawSample, d.Protocol, d.Patient, " +
				" tt.Display AS Test, u.Display AS Units, t.Location, t.IsTestCheckOut, t.TestOutTo, " +
				" t.OutTo, t.OutDate, t.Result, t.Note, t.BatchOutNum " +
				" FROM TestSamples t,DrawSamples d, TestType_L tt, UnitOfMeasure_L u " +
				" WHERE 1=2 AND d.ID=t.DrawSample AND t.TestType=tt.ID AND t.UnitOfMeasure=u.ID";

			try
			{
				this._tableSchema = Forms.Utils.GetTableSchema(null, sql);

				InitializeGridControl();
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve grid table schema!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Grid Data Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}

		private void InitializeGridControl()
		{
			this._grid.BeginUpdate();
			//this adds up the total column width
			int totColWidth = 0;

			int col = 1;
			//create the new grid columns for drawSamples			
			this._grid.ColCount = this._formGridMeta.GridColumns.Count;
			//start with drawSamples table
			foreach (DataColumn dc in this._tableSchema.Columns)
			{
				//get the metadata for this column
				if (!this._formGridMeta.GridColumns.Contains(dc.ColumnName))
					continue;

				FormGridColumnMeta fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumns[dc.ColumnName];
				//store the dataColum in the tag property
				//in the header row
				this._grid[0, col].Tag = dc;
				this._grid[0, col].Text = fgcm.DisplayName;
				GridStyleInfo gsi = this._grid.ColStyles[col];
				gsi.CellType = fgcm.CellType;
				gsi.Enabled = true;
				//gsi.Text = fgcm.DisplayName;

				if (fgcm.CellType == "CheckBox")
				{
					gsi.CheckBoxOptions = new GridCheckBoxCellInfo("1", "0", "", true);
					gsi.TriState = false;
					gsi.CellValueType = typeof(string);
					gsi.CellValue = "0";

				}
				else
				{
					gsi.CellValue = null;
					gsi.CellValueType = Type.GetType(fgcm.DataType);

					if (fgcm.CellType == "ComboBox")
					{
						BindGridColumn(fgcm, gsi);
						gsi.DropDownStyle = GridDropDownStyle.AutoComplete;
						//gsi.ReadOnly = false;
					}
				}

				this._grid.ColWidths[col] = fgcm.Width;
				totColWidth += fgcm.Width;
				if (fgcm.IsHidden)
					this._grid.Cols.Hidden[col] = true;
				if (fgcm.ReadOnly)
					gsi.ReadOnly = true;
				col++;
			}

			HookGridEvents();

			//			if(totColWidth < MaxWidth)
			//				this._grid.Width = totColWidth + 60;

			this._grid.ResizeRowsBehavior = GridResizeCellsBehavior.None;
			this._grid.Model.RowHeights.ResizeToFit(GridRangeInfo.Row(0), GridResizeToFitOptions.IncludeHeaders);
			this._grid.EndUpdate();
		}
		#endregion initialize

		#region events
		protected override void grid_CurrentCellShowingDropDown(object sender, GridCurrentCellShowingDropDownEventArgs e)
		{
			GridCurrentCell cc = this._grid.CurrentCell;
			if (this._grid.ColStyles[cc.ColIndex].ReadOnly)
			{
				e.Cancel = true;
				return;
			}
			if (this._grid[cc.RowIndex, cc.ColIndex].ReadOnly)
				e.Cancel = true;


		}

		protected override void grid_PrepareViewStyleInfo(object sender, GridPrepareViewStyleInfoEventArgs e)
		{
			int row = e.RowIndex;
			int col = e.ColIndex;
			if (row > 0 && col > 0)
			{
				if (_grid.ColStyles[col].ReadOnly)
				{
					e.Style.BackColor = Color.LightGray;
					return;
				}
				if (_grid[row, col].ReadOnly)
					e.Style.BackColor = Color.LightGray;

			}
		}

		protected override void Grid_CurrentCellChanged(object sender, EventArgs e)
		{
			base.Grid_CurrentCellChanged(sender, e);

			StringBuilder sb = new StringBuilder();
			GridCurrentCell cc = this._grid.CurrentCell;
			int col = cc.ColIndex;
			int row = cc.RowIndex;
			GridStyleInfo gsi1 = null;
			GridStyleInfo gsi2 = null;

			this._grid.IgnoreReadOnly = true;
			if (col == 8)
			{
				if (_grid[row, 8].Text == "1")
				{
					//get rid of the location
					if (this._grid[row, 7].Text.Length > 0)
					{
						this._grid[row, 7].Text = "";
						AssignChangeToDataRow(row, 7);
					}

					gsi1 = this._grid[row, 10];
					//make outTo readOnly
					if (gsi1.Text.Length > 0)
					{
						gsi1.Text = "";
						AssignChangeToDataRow(row, 10);
					}
					gsi1.ReadOnly = true;

					gsi2 = this._grid[row, 9];
					//make testOutTo not readOnly					
					gsi2.ReadOnly = false;
				}
				else
				{
					gsi1 = this._grid[row, 10];
					//make outTo not readOnly					
					gsi1.ReadOnly = false;

					gsi2 = this._grid[row, 9];
					//make testOutTo readOnly
					if ((int)gsi2.CellValue > -1)
					{
						gsi2.CellValue = -1;
						AssignChangeToDataRow(row, 9);
					}
					gsi2.ReadOnly = true;
				}
				AssignChangeToDataRow(row, 8);
			}
			if (col == 10)
			{
				//get rid of the location
				if (this._grid[row, 7].Text.Length > 0)
				{
					this._grid[row, 7].Text = "";
					AssignChangeToDataRow(row, 7);
				}
			}
			this._grid.IgnoreReadOnly = false;


		}
		#endregion events

		#region add replace remove
		public override void ReplaceRow(object obj, int row)
		{
			DataRow dr = (DataRow)this._grid[row, 0].Tag;
			Sample samp = (Sample)obj;

			this._grid.IgnoreReadOnly = true;

			if (samp.IsTestCheckOut)
			{
				//check tester for selected in editer 
				if (samp.TestOutTo > -1)
				{
					//row 8 is 'IsTestCheckOut'
					if (this._grid[row, 8].CellValue.ToString() == "0")
					{
						this._grid[row, 8].CellValue = 1;
						AssignChangeToDataRow(row, 8);

						//tester
						this._grid[row, 9].ReadOnly = false;

						//get rid of out to
						if (this._grid[row, 10].Text.Length > 0)
						{
							this._grid[row, 10].Text = "";
							AssignChangeToDataRow(row, 10);
						}
						this._grid[row, 10].ReadOnly = true;
					}

					//tester
					if ((int)this._grid[row, 9].CellValue != samp.TestOutTo)
					{
						this._grid[row, 9].CellValue = samp.TestOutTo;
						AssignChangeToDataRow(row, 9);
					}

					//get rid of the location
					if (this._grid[row, 7].Text.Length > 0)
					{
						this._grid[row, 7].Text = "";
						AssignChangeToDataRow(row, 7);
					}
				}
			}
			else //not isTestCheckOut
			{
				if (samp.OutTo.Length > 0)
				{
					if (this._grid[row, 8].CellValue.ToString() == "1")
					{
						this._grid[row, 8].CellValue = 0;
						AssignChangeToDataRow(row, 8);

						//tester					
						if ((int)this._grid[row, 9].CellValue > -1)
						{
							this._grid[row, 9].CellValue = -1;
							AssignChangeToDataRow(row, 9);
						}
						this._grid[row, 9].ReadOnly = true;
						//out to
						this._grid[row, 10].ReadOnly = false;
					}
					//get rid of the location
					if (this._grid[row, 7].Text.Length > 0)
					{
						this._grid[row, 7].Text = "";
						AssignChangeToDataRow(row, 7);
					}
					//out to
					if (this._grid[row, 10].Text != samp.OutTo)
					{
						this._grid[row, 10].Text = samp.OutTo;
						AssignChangeToDataRow(row, 10);
					}
				}
			}

			if (samp.OutDate != CremaConstants.NullDate)
			{
				this._grid[row, 11].CellValue = samp.OutDate;
				this._grid[row, 11].Format = "MM/dd/yyyy";
				AssignChangeToDataRow(row, 11);
			}

			if (samp.Result.Length > 0)
			{
				this._grid[row, 12].Text = samp.Result.Trim();
				AssignChangeToDataRow(row, 12);
			}

			if (samp.Note.Length > 0)
			{
				this._grid[row, 13].Text = samp.Note.Trim();
				AssignChangeToDataRow(row, 13);
			}
			this._grid.IgnoreReadOnly = false;
		}

		public override void AddRow(object obj, int row)
		{
			this._grid.IgnoreReadOnly = true;
			Sample samp = (Sample)obj;
			DataRow dr = _data.NewRow();
			this._data.Rows.Add(dr);

			int rows = ++this._grid.RowCount;

			this._grid[rows, 0].Tag = dr;

			this._grid[rows, 1].CellValue = samp.TestID;
			AssignChangeToDataRow(rows, 1);
			this._grid[rows, 2].CellValue = samp.DrawID;
			AssignChangeToDataRow(rows, 2);
			this._grid[rows, 3].CellValue = samp.Protocol;
			this._grid[rows, 3].Tag = samp.ProtocolInfo;
			this._grid[rows, 3].CellTipText = samp.ProtocolInfo.GetToolTip();
			AssignChangeToDataRow(rows, 3);
			this._grid[rows, 4].CellValue = samp.PatientInfo.GetMrnOrOtherIdentifier();
			this._grid[rows, 4].Tag = samp.PatientInfo;
			this._grid[rows, 4].CellTipText = samp.PatientInfo.GetToolTip();
			//AssignChangeToDataRow(rows, 4);

			this._grid[rows, 5].CellValue = samp.TestName;
			AssignChangeToDataRow(rows, 5);
			this._grid[rows, 6].CellValue = samp.UnitOfMeasureName;
			AssignChangeToDataRow(rows, 6);
			this._grid[rows, 7].CellValue = samp.Location;
			AssignChangeToDataRow(rows, 7);
			this._grid[rows, 9].CellValue = samp.TestOutTo;
			AssignChangeToDataRow(rows, 9);
			this._grid[rows, 10].CellValue = samp.OutTo;
			AssignChangeToDataRow(rows, 10);

			if (samp.IsTestCheckOut)
			{
				this._grid[rows, 8].Text = "1";
				this._grid[rows, 10].ReadOnly = true;
			}
			else
			{
				this._grid[rows, 8].Text = "0";
				this._grid[rows, 9].ReadOnly = true;
			}
			AssignChangeToDataRow(rows, 8);

			if (samp.OutDate == CremaConstants.NullDate)
				this._grid[rows, 11].Text = "";
			else
			{
				this._grid[rows, 11].CellValue = samp.OutDate;
				this._grid[rows, 11].Format = "MM/dd/yyyy";
			}
			AssignChangeToDataRow(rows, 11);

			this._grid[rows, 12].CellValue = samp.Result;
			AssignChangeToDataRow(rows, 12);
			this._grid[rows, 13].Text = samp.Note;
			AssignChangeToDataRow(rows, 13);
			this._grid.IgnoreReadOnly = false;
			this._grid.ScrollCellInView(this._grid.RowCount, 0);
		}
		#endregion add replace remove
		public override void New()
		{
			//just create an empty table where we can add new rows
			string sql = "SELECT t.ID, t.DrawSample, d.Protocol, d.Patient, " +
				" tt.Display AS Test, u.Display AS Units, t.Location, t.IsTestCheckOut, t.TestOutTo, " +
				" t.OutTo, t.OutDate, t.Result, t.Note, t.BatchOutNum " +
				" FROM TestSamples t,DrawSamples d, TestType_L tt, UnitOfMeasure_L u " +
				" WHERE 1=2 AND d.ID=t.DrawSample AND t.TestType=tt.ID AND t.UnitOfMeasure=u.ID";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			StringBuilder sb = new StringBuilder();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_data = ds.Tables[0];
				this._grid.RowCount = 0;
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve new empty grid table!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Grid Table Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}

		}

		#region get display data
		public override void SetEnabled(bool enable)
		{
			GridStyleInfo gsi = null;
			FormGridColumnMeta fgcm = null;

			this._grid.IgnoreReadOnly = true;
			if (enable)
			{
				if (this._grid.RowCount > 0)
				{

					this._btnRemoveBatch.Enabled = true;
					this._btnEditBatch.Enabled = true;
				}
				//enable non-readonly cols
				for (int i = 1; i <= this._grid.ColCount; i++)
				{
					fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumnsOrdered[i - 1];
					gsi = this._grid.ColStyles[i];
					if (!fgcm.ReadOnly)
						gsi.ReadOnly = false;
				}
			}
			else
			{
				//disable non-readonly cols				
				for (int i = 1; i <= this._grid.ColCount; i++)
				{
					fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumnsOrdered[i - 1];
					gsi = this._grid.ColStyles[i];
					if (!fgcm.ReadOnly)
						gsi.ReadOnly = true;
				}
			}
			this._grid.IgnoreReadOnly = false;
		}

		public override bool GetData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT t.ID, t.DrawSample, d.Protocol, d.Patient, " +
				" tt.Display AS Test, u.Display AS Units, t.Location, t.IsTestCheckOut, t.TestOutTo, " +
				" t.OutTo, t.OutDate, t.Result, t.Note, t.BatchOutNum " +
				" FROM TestSamples t,DrawSamples d, TestType_L tt, UnitOfMeasure_L u " +
				" WHERE t.BatchOutNum =" + id +
				" AND d.ID=t.DrawSample " +
				" AND t.TestType = tt.ID " +
				" AND t.UnitOfMeasure=u.ID " +
				" ORDER BY t.ID";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_data = ds.Tables[0];

				this._grid.BeginUpdate();
				this._grid.RowCount = 0;

				this._grid.RowCount = _data.Rows.Count;
				int row = 1;
				foreach (DataRow dr in _data.Rows)
				{
					//store the dataRow in the cell.tag of the header column
					this._grid[row, 0].Tag = dr;
					DisplayRow(row, dr);
					row++;
				}
				this._grid.EndUpdate();
				if (this._grid.RowCount > 0)
					this._btnPrint.Enabled = true;
				else
					this._btnPrint.Enabled = false;


			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message);
				//TODO - need to do more here for exception				
				MessageBox.Show("GetGridData Exception");
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
			return true;

		}

		protected override void DisplayRow(int row, DataRow dr)
		{
			string message = "";
			this._grid.IgnoreReadOnly = true;
			for (int i = 1; i < this._grid.ColCount + 1; i++)
			{
				DataColumn dc = (DataColumn)this._grid[0, i].Tag;

				if (this._grid[row, i].CellType == "CheckBox")
				{
					if (dr[dc.ColumnName] != System.DBNull.Value)
					{
						if ((bool)dr[dc.ColumnName])
							this._grid[row, i].CellValue = "1";
						else
							this._grid[row, i].CellValue = "0";
					}
				}
				else
					this._grid[row, i].CellValue = dr[dc.ColumnName];
				if (this._grid[row, i].CellType == "MonthCalendar")
					this._grid[row, i].Format = "MM/dd/yyyy";

				if (dc.ColumnName == "Protocol")
				{
					int protocol = Convert.ToInt32(dr[dc.ColumnName]);
					ProtocolInfo pi = CoreLabUtils.GetProtocolInfo(protocol, out message);
					this._grid[row, i].Tag = pi;
					if (pi.ID > -1)
						this._grid[row, i].CellTipText = pi.GetToolTip();
				}
				if (dc.ColumnName == "Patient")
				{
					int patient = Convert.ToInt32(dr[dc.ColumnName]);
					PatientInfo pi = CoreLabUtils.GetPatientInfo(patient, out message);
					this._grid[row, i].Tag = pi;
					if (pi.ID > -1)
						this._grid[row, i].CellTipText = pi.GetToolTip();
					this._grid[row, i].CellValue = pi.GetMrnOrOtherIdentifier();
				}
				if (dc.ColumnName == "IsTestCheckOut")
				{
					if (this._grid[row, i].CellValue.ToString() == "1")
						this._grid[row, i + 2].ReadOnly = true;
					else
						this._grid[row, i + 1].ReadOnly = true;
				}
			}
			_grid.IgnoreReadOnly = false;
		}
		#endregion get display data

		#region save
		public override bool Save(int foreignID, out string message, Database db, DbTransaction trans)
		{
			message = "";
			if (_data == null)
				return true;

			foreach (DataRow dr in _data.Rows)
			{
				//do an update for both added (record already exists, it's just being tied to 
				//this check-out batch number) and modified
				if (dr.RowState == DataRowState.Added || dr.RowState == DataRowState.Modified)
				{
					if (!UpdateRow(dr, foreignID, out message, db, trans))
						return false;
				}
			}
			return true;
		}

		private bool UpdateRow(DataRow dr, int foreignID, out string message, Database db, DbTransaction trans)
		{
			message = "";

			//sql update
			string sqlUpdate = "UPDATE TestSamples Set Location=@Location, Note=@Note, " +
				" IsTestCheckOut=@IsTestCheckOut, TestOutTo=@TestOutTo, OutTo=@OutTo, " +
				" Result=@Result, BatchOutNum=@BatchOutNum, OutDate=@OutDate " +
				" WHERE ID=@ID";

			//sql parameters
			SqlParameter[] aParams = new SqlParameter[9];
			aParams[0] = new SqlParameter("@Location", SqlDbType.NVarChar, 50, "Location");
			aParams[1] = new SqlParameter("@Note", SqlDbType.NVarChar, 4000, "Note");
			aParams[2] = new SqlParameter("@IsTestCheckOut", SqlDbType.Bit, 0, "IsTestCheckOut");
			aParams[3] = new SqlParameter("@TestOutTo", SqlDbType.Int, 0, "TestOutTo");
			aParams[4] = new SqlParameter("@OutTo", SqlDbType.NVarChar, 50, "OutTo");
			aParams[5] = new SqlParameter("@Result", SqlDbType.NVarChar, 255, "Result");
			aParams[6] = new SqlParameter("@BatchOutNum", SqlDbType.Int, 0, "BatchOutNum");
			aParams[7] = new SqlParameter("@OutDate", SqlDbType.DateTime, 0, "OutDate");
			aParams[8] = new SqlParameter("@ID", SqlDbType.Int, 0, "ID");


			//assign parameters
			AssignParameters(aParams, dr, foreignID, 0);


			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlUpdate);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				//SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sqlUpdate, aParams);				
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return false;
			}
			return true;
		}
		#endregion save

		#region verify
		protected override bool VerifyRow(int row, int validationType)
		{
			GridControl grid = this._grid;
			StringBuilder sb = new StringBuilder();
			//			string errMessage = "";
			//			string errMsgKey = "";

			//make sure that we have a date and either outTo or tester entered.
			//row 8 is 'IsTestCheckOut'
			if (this._grid[row, 8].CellValue.ToString() == "0")
			{
				//row 10 is 'OutTo'
				if (this._grid[row, 10].Text.Trim().Length == 0)
				{
					//					errMsgKey = row + ": Out To";
					//					if(this._errMessages.Contains(errMsgKey))
					//						this._errMessages.Remove(errMsgKey);
					sb.Append("Row:" + row + "," + "Col: Out To");
					sb.Append(Environment.NewLine);
					sb.Append("You need to enter the a name in the 'Out To' column.");
					//this._errMessages.Add(errMsgKey, sb.ToString());
					MessageBox.Show(this._form, sb.ToString(), "Data Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return false;
				}
			}
			else //need a tester		
			{
				//row 9 is 'Tester'
				if (this._grid[row, 9].Text == "-1")
				{
					//					errMsgKey = row + ": Tester";
					//					if(this._errMessages.Contains(errMsgKey))
					//						this._errMessages.Remove(errMsgKey);
					sb.Append("Row:" + row + "," + "Col: Tester");
					sb.Append(Environment.NewLine);
					sb.Append("You need to enter the a name in the 'Tester' column.");
					//this._errMessages.Add(errMsgKey, sb.ToString());
					MessageBox.Show(this._form, sb.ToString(), "Data Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return false;
				}
			}

			//verify out date - row 11
			if (this._grid[row, 11].CellValue == System.DBNull.Value)
			{
				sb.Append("Row:" + row + "," + "Col: Out Date");
				sb.Append(Environment.NewLine);
				sb.Append("You need to enter a date in the 'Out Date' column.");
				MessageBox.Show(this._form, sb.ToString(), "Data Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				return false;
			}
			else
			{
				DateTime dt = (DateTime)this._grid[row, 11].CellValue;
				if (dt == CremaConstants.NullDate)
				{
					//				errMsgKey = row + ": Out Date";
					//				if(this._errMessages.Contains(errMsgKey))
					//					this._errMessages.Remove(errMsgKey);
					sb.Append("Row:" + row + "," + "Col: Out Date");
					sb.Append(Environment.NewLine);
					sb.Append("You need to enter a date in the 'Out Date' column.");
					//this._errMessages.Add(errMsgKey, sb.ToString());
					MessageBox.Show(this._form, sb.ToString(), "Data Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return false;
				}
			}
			return true;
		}
		#endregion verify

	}
}
